package com.meme.editor.model.sprite2d;

import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import org.apache.log4j.Logger;

import com.meme.editor.EntityObject;

public class Tiled2dPalette extends Tiled2dGrid 
{
	static Logger logger = Logger.getLogger (Tiled2dPalette.class);

	public static final int DefaultCellWidth = 32;
	public static final int DefaultCellHeight = 32;
	

	public static final int MaxCellRows = 32;
	public static final int MaxCellCols = 32;
	

	public Tiled2dPalette ()
	{
		super (DefaultCellWidth, DefaultCellHeight, 2, 16);
	}
	
	@Override
	public void swapChildren (int one, int another)
	{
		super.swapChildren(one, another);
		
		Tiled2dModule tile1 = (Tiled2dModule) getChildByIndex (one);
		Tiled2dModule tile2 = (Tiled2dModule) getChildByIndex (another);
		int row1 = tile1.getRow ();
		int col1 = tile1.getCol ();
		int row2 = tile2.getRow ();
		int col2 = tile2.getCol ();
		
		tile1.setPosInGrid (row2, col2);
		tile2.setPosInGrid (row1, col1);
		tile1.setPosInGrid (row2, col2); // to correct the name
	}
	
	@Override
	public String getDefaultName ()
	{
		return "Tile Palette";
	}
	
	public Tiled2dModule getTiled2dModuleByName (String name)
	{
		// return (Tiled2dModule) getChildByName(name);
		
		int _pos = name.indexOf(',');
		int cellRow = Integer.parseInt(name.substring(0, _pos));
		int cellCol = Integer.parseInt(name.substring(_pos + 1));
		
		return getTiled2dModuleByPos (cellRow, cellCol);
	}
	
	public Tiled2dModule getTiled2dModuleByIndex (int index)
	{
		return (Tiled2dModule) getChildByIndex(index);
	}
	
	public Tiled2dModule getTiled2dModuleByPos (int cellRow, int cellCol)
	{
		logger.assertLog(cellCol >= 0 && cellCol < mCellCols, "cellCol is out of range");
		logger.assertLog(cellRow >= 0 && cellRow < mCellRows, "cellRow is out of range");
		
		if ( ! (cellCol >= 0 && cellCol < mCellCols && cellRow >= 0 && cellRow < mCellRows) )
			return null;
		
		return getTiled2dModuleByIndex ( cellCol + cellRow * getCellCols () );
	}



	@Override int getMaxCellRows () {return MaxCellRows;}
	@Override int getMaxCellCols () {return MaxCellCols;}
	
	@Override
	protected void handleGridSizeChanged (int oldRows, int oldCols)
	{
		//_handleGridSizeChanged_StandardRoute (oldRows, oldCols);
		_handleGridSizeChanged_EfficentRoute (oldRows, oldCols);
	}
	
	void _handleGridSizeChanged_StandardRoute (int oldRows, int oldCols)
	{
		int min_rows = oldRows < mCellRows ? oldRows : mCellRows;

		
		// if (oldCols < mCellCols)
		for (int row = 0; row < min_rows; ++ row)
		{
			for (int col = oldCols; col < mCellCols; ++ col)
			{
				insertChild (new Tiled2dModule (this, row, col), row * mCellCols + col);
			}
		}
		// if (oldCols > mCellCols)
		for (int row = 0; row < min_rows; ++ row)
		{
			for (int col = mCellCols; col < oldCols; ++ col)
			{
				removeChild (row * mCellCols + mCellCols);
			}
		}
		// if (oldRows < mCellRows)
		for (int row = oldRows; row < mCellRows; ++ row)
		{
			for (int col = 0; col < mCellCols; ++ col)
			{
				addChild (new Tiled2dModule (this, row, col));
			}
		}
		// if (oldRows > mCellRows)
		for (int row = mCellRows; row < oldRows; ++ row)
		{
			for (int col = 0; col < oldCols; ++ col)
			{
				removeChild (mCellRows * mCellCols);
			}
		}

	}

	void _handleGridSizeChanged_EfficentRoute (int oldRows, int oldCols)
	{
		Vector<EntityObject> childList = (Vector<EntityObject>) getChildren ();
		List<EntityObject> entityList = new LinkedList <EntityObject> ();
		
		// find children to be removed
		for ( int row = 0; row < mCellRows; ++ row )
		{
			for ( int col = 0; col < mCellCols; ++ col )
			{
				
			}
		}
		
		for (EntityObject child : childList)
		{
			Tiled2dModule tile = (Tiled2dModule) child;
			if ( tile.getRow () >= mCellRows || tile.getCol() >= mCellCols )
				entityList.add (child);
		}
		
		// remove
		for (EntityObject child : entityList)
		{
			removeChild (child);
		}
		
		// backup remaining children
		entityList.clear();
		entityList.addAll(childList);
		
		// resize children list
		childList.clear();
		childList.setSize(mCellRows * mCellCols);
		
		// put back remaining children
		for (EntityObject child : entityList)
		{
			Tiled2dModule tile = (Tiled2dModule) child;
			int index = tile.getRow () * mCellCols + tile.getCol();
			//childList.set(index, tile);
			replaceChild (index, tile);
		}
		
		// create new children
		for ( int row = 0; row < mCellRows; ++ row )
		{
			for ( int col = 0; col < mCellCols; ++ col )
			{
				if (row >= oldRows || col >= oldCols)
					replaceChild ( row * mCellCols + col, new Tiled2dModule (row, col) );
			}
		}
	}


}
